#!/usr/bin/env python3
"""
KF5-Solid MCP Server

面向 kf5-solid 软件包的 MCP 服务器，提供硬件设备管理相关的命令行工具封装。

MCP tools 列表：
1. solid_details - 获取设备详细信息
   - 参数：udi (str) - 设备 UDI 标识符
   - 返回：统一的命令执行结果 JSON

2. solid_eject - 弹出可移动设备
   - 参数：udi (str) - 设备 UDI 标识符
   - 返回：统一的命令执行结果 JSON

3. solid_listen - 监听硬件变化事件
   - 参数：无
   - 返回：统一的命令执行结果 JSON

4. solid_mount - 挂载设备
   - 参数：udi (str) - 设备 UDI 标识符
   - 返回：统一的命令执行结果 JSON

5. solid_nonportableinfo - 获取非便携设备信息
   - 参数：udi (str) - 设备 UDI 标识符
   - 返回：统一的命令执行结果 JSON

6. solid_query - 查询设备属性
   - 参数：predicate (str) - 查询谓词，parent_udi (str, 可选) - 父设备 UDI
   - 返回：统一的命令执行结果 JSON

7. solid_power - 电源管理操作
   - 参数：command (str) - 电源管理命令
   - 返回：统一的命令执行结果 JSON

8. solid_unmount - 卸载设备
   - 参数：udi (str) - 设备 UDI 标识符
   - 返回：统一的命令执行结果 JSON

所有工具返回统一的 JSON 结构：
{
    "success": bool,
    "command": str,
    "exit_code": int,
    "stdout": str,
    "stderr": str
}
"""

import subprocess
import shlex
from typing import Optional
from mcp.server.fastmcp import FastMCP, Context

mcp = FastMCP("KF5-Solid MCP Server")


def run_command(command: str) -> dict:
    """执行 shell 命令并返回统一格式的结果"""
    try:
        result = subprocess.run(
            command,
            shell=True,
            capture_output=True,
            text=True,
            timeout=30
        )
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout.strip(),
            "stderr": result.stderr.strip()
        }
    except subprocess.TimeoutExpired:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": "Command timed out after 30 seconds"
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Command execution failed: {str(e)}"
        }


@mcp.tool()
def solid_details(udi: str) -> dict:
    """
    获取设备的详细信息
    
    参数:
        udi (str): 设备 UDI 标识符
    
    返回:
        dict: 统一的命令执行结果 JSON
    """
    command = f"solid-hardware5 details {shlex.quote(udi)}"
    return run_command(command)


@mcp.tool()
def solid_eject(udi: str) -> dict:
    """
    弹出指定的可移动设备
    
    参数:
        udi (str): 设备 UDI 标识符
    
    返回:
        dict: 统一的命令执行结果 JSON
    """
    command = f"solid-hardware5 eject {shlex.quote(udi)}"
    return run_command(command)


@mcp.tool()
def solid_listen() -> dict:
    """
    监听硬件设备的变化事件
    
    返回:
        dict: 统一的命令执行结果 JSON
    """
    command = "solid-hardware5 listen"
    return run_command(command)


@mcp.tool()
def solid_mount(udi: str) -> dict:
    """
    挂载指定的设备
    
    参数:
        udi (str): 设备 UDI 标识符
    
    返回:
        dict: 统一的命令执行结果 JSON
    """
    command = f"solid-hardware mount {shlex.quote(udi)}"
    return run_command(command)


@mcp.tool()
def solid_nonportableinfo(udi: str) -> dict:
    """
    获取非便携设备的信息
    
    参数:
        udi (str): 设备 UDI 标识符
    
    返回:
        dict: 统一的命令执行结果 JSON
    """
    command = f"solid-hardware5 nonportableinfo {shlex.quote(udi)}"
    return run_command(command)


@mcp.tool()
def solid_query(predicate: str, parent_udi: Optional[str] = None) -> dict:
    """
    查询设备属性
    
    参数:
        predicate (str): 查询谓词，如 'isDisk'
        parent_udi (str, 可选): 父设备 UDI
    
    返回:
        dict: 统一的命令执行结果 JSON
    """
    if parent_udi:
        command = f"solid-hardware5 query {shlex.quote(predicate)} {shlex.quote(parent_udi)}"
    else:
        command = f"solid-hardware5 query {shlex.quote(predicate)}"
    return run_command(command)


@mcp.tool()
def solid_power(command: str) -> dict:
    """
    执行电源管理相关操作
    
    参数:
        command (str): 电源管理命令
    
    返回:
        dict: 统一的命令执行结果 JSON
    """
    full_command = f"solid-power {shlex.quote(command)}"
    return run_command(full_command)


@mcp.tool()
def solid_unmount(udi: str) -> dict:
    """
    卸载指定的设备
    
    参数:
        udi (str): 设备 UDI 标识符
    
    返回:
        dict: 统一的命令执行结果 JSON
    """
    command = f"solid-hardware unmount {shlex.quote(udi)}"
    return run_command(command)


if __name__ == "__main__":
    mcp.run()